package modelo;

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;

import modelo.Ponto;
import modelo.Reta;

public class ViewPort extends FiguraGeometrica{

	Retangulo retangulo;
	List<FiguraGeometrica> figuras = new ArrayList<FiguraGeometrica>();

	private static final String DIREITA = "Direita";
	private static final String ESQUERDA = "Esquerda";
	private static final String INFERIOR = "Inferior";
	private static final String SUPERIOR = "Superior";

	public ViewPort(Retangulo r){
		this.retangulo = r;
	}

	public void adicionaFiguras(List<FiguraGeometrica> f){
		for(FiguraGeometrica fig : f){
			arrumaDesenho(fig);
		}
	}

	public void arrumaDesenho(FiguraGeometrica f){
		ArrayList<String> direcoes;
		Ponto corte;
		if (f instanceof Reta) {
			Reta r = (Reta) f;

			ArrayList<String> dir_inic = regiao(r.getP1());
			ArrayList<String> dir_fim = regiao(r.getP2());

			while (dir_inic.size() != 0 || dir_fim.size() != 0) {
				if (direcaoComum(dir_inic, dir_fim)) {
					dir_inic = new ArrayList<String>();
					dir_fim = new ArrayList<String>();
					r = new Reta(new Ponto(-1,-1),new Ponto(-1,-1));
				} else {
					if (dir_inic.size() == 0) {
						direcoes = dir_fim;
					} else {
						direcoes = dir_inic;
					}

					// Cortes contra as bordas
					if (direcoes.indexOf(ESQUERDA) != -1) {
						corte = corteVertical(r, retangulo.getXMenor());
					} else if (direcoes.indexOf(DIREITA) != -1) {
						corte = corteVertical(r, retangulo.getXMaior());						
					}else if (direcoes.indexOf(SUPERIOR) != -1){
						corte = corteHorizontal(r, retangulo.getYMenor());
					}else{
						corte = corteHorizontal(r, retangulo.getYMaior());
					}
					if (direcoes == dir_inic) {
						r = new Reta(corte,r.getP2());
						dir_inic = regiao(r.getP1());
						direcoes = null;
					} else {
						r = new Reta(r.getP1(),corte);
						dir_fim = regiao(r.getP2());
						direcoes = null;
					}
				}				
			}
			figuras.add(r);
		}
	}

	private Ponto corteVertical(Reta r, int xw) {
		int y = (int) (r.getM() * (xw - r.getP1().getX())) + r.getP1().getY();
		return new Ponto(xw, y);
	}
	private Ponto corteHorizontal(Reta r, int yw) {
		//System.out.println(r.cruzamento(new Reta(new Ponto(retangulo.getXMenor(),yw),new Ponto(retangulo.getXMaior(),yw))).show());
		//System.out.println(r.getM()+" "+r.getMInverse());
		int x = (int) ( r.getP1().getX()+ ((yw - r.getP1().getY())/r.getM()));
		return new Ponto(x,yw);
	}

	private boolean direcaoComum(ArrayList<String> direcao1,
			ArrayList<String> direcao2) {
		for (String d1 : direcao1) {
			for (String d2 : direcao2) {
				if (d1.equals(d2))
					return true;
			}
		}
		return false;
	}

	private ArrayList<String> regiao(Ponto p) {
		int x = p.getX();
		int y = p.getY();
		ArrayList<String> direcao = new ArrayList<String>();
		if (x >= retangulo.getXMenor() && x <= retangulo.getXMaior()
				&& y >= retangulo.getYMenor() && y <= retangulo.getYMaior()) {
			return direcao;
		}

		if (x < retangulo.getXMenor()) {
			direcao.add(ESQUERDA);
		} else if (x > retangulo.getXMaior()) {
			direcao.add(DIREITA);
		}
		if (y < retangulo.getYMenor()) {
			direcao.add(SUPERIOR);
		} else if (y > retangulo.getYMaior()) {
			direcao.add(INFERIOR);
		}
		return direcao;
	}

	/*@Override
	public void plotar(Graphics g) {
		retangulo.plotar(g);
		for (FiguraGeometrica f : figuras) {
			f.plotar(g);
		}		
	}*/	
}
